package codeGeneration;

import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;
import java.util.Set;

import lexer.TokenConstant;

public class GenerateSetOfRule {
	private static GenerateSetOfRule sor = null;

	private GenerateSetOfRule() {
	}

	public static GenerateSetOfRule getSetOfRule() {
		if (sor == null)
			sor = new GenerateSetOfRule();

		return sor;
	}

	public void generateEmailRule() {

	}

	public String generateCheckGeneral(String[] spaces, int indentIndex,
			String actionFormName, String nameOfControl, int type,
			Properties propOfMessages) {
		StringBuffer sbuff = new StringBuffer();
		String regex = "";
		String messagesCode = "";
		String messagesContent = "";

		switch (type) {
		case TokenConstant.CHECKNUMERIC:
			regex = "^\\\\d*$";
			messagesCode = "text.checknumeric";
			messagesContent = "This field must be nummeric";
			break;
		case TokenConstant.CHECKALPHA:
			regex = "^\\\\W*$";
			messagesCode = "text.checkalpha";
			messagesContent = "This field must not contain digit";
			break;
		case TokenConstant.CHECKPHONENUMBER:
			regex = "^\\\\d*$";
			messagesCode = "text.checkphonenumber";
			messagesContent = "This field must be phone number";
			break;
		case TokenConstant.CHECKEMAIL:
			regex = "^([0-9a-zA-Z]([-.\\\\w]*[0-9a-zA-Z])*@([0-9a-zA-Z]"
					+ "[-\\\\w]*[0-9a-zA-Z]\\\\.)+[a-zA-Z]{2,9})$";
			messagesCode = "text.checkemail";
			messagesContent = "This field must follow email rules";
			break;
		case TokenConstant.CHECKEMPTY:
			regex = "^([\\\\s]*[\\\\w]+[\\\\s]*)+";
			messagesCode = "text.checkempty";
			messagesContent = "This field can not be blank!";
			break;
		}

		sbuff.append("\n");
		sbuff.append(spaces[indentIndex] + "if (!Pattern.matches (\"" + regex
				+ "\", "
				+ getValueFromActionForm(actionFormName, nameOfControl)
				+ ")) {\n");

		++indentIndex;

		sbuff.append(spaces[indentIndex] + "errors.rejectValue(");
		sbuff.append("\"" + nameOfControl + "\",\"" + messagesCode + "\");\n");

		--indentIndex;
		sbuff.append(spaces[indentIndex] + "}\n");

		propOfMessages.setProperty(messagesCode, messagesContent);

		return sbuff.toString();
	}

	public String generateCheckDate(String[] spaces, int indentIndex,
			String actionFormName, String nameOfControl, int typeOfControl,
			String dateFormat, Properties propOfMessage) {
		StringBuffer sbuff = new StringBuffer();
		String messagesCode = "";
		String messagesContent = "";

		switch (typeOfControl) {
		case TokenConstant.TEXTFIELD:
		case TokenConstant.TEXTAREA:

			sbuff.append("	try {\n");
			sbuff.append("	SimpleDateFormat sdf = new SimpleDateFormat("
					+ dateFormat + ");\n");
			sbuff.append("	sdf.setLenient(false);\n");
			sbuff.append("	Date date = sdf.parse("
					+ getValueFromActionForm(actionFormName, nameOfControl)
					+ ");\n");
			sbuff.append("} catch (ParseException e) {\n");
			++indentIndex;
			sbuff.append(spaces[indentIndex] + "errors.rejectValue(");
			sbuff.append("\"" + nameOfControl + "\", \"text.checkdate\");\n");
			--indentIndex;
			sbuff.append(spaces[indentIndex] + "}\n");

			messagesCode = "text.checkdate";
			messagesContent = "This field must follow date format";
			break;
		}

		propOfMessage.setProperty(messagesCode, messagesContent);

		return sbuff.toString();
	}

	public String generateChecklength(String[] spaces, int indentIndex,
			String actionFormName, String nameOfControl, int typeOfControl,
			int minLength, int maxLength, Properties propOfMessage) {
		StringBuffer sbuff = new StringBuffer();

		if (typeOfControl != 0) {
			String messagesCode = "";
			String messagesContent = "";

			switch (typeOfControl) {
			case TokenConstant.TEXTFIELD:
			case TokenConstant.TEXTAREA:
				sbuff.append("\n");
				sbuff.append(spaces[indentIndex] + "if ("
						+ getValueFromActionForm(actionFormName, nameOfControl)
						+ ".length()" + " < " + minLength + " || "
						+ getValueFromActionForm(actionFormName, nameOfControl)
						+ ".length()" + " > " + maxLength + ") {\n");

				break;
			}
			++indentIndex;
			sbuff.append(spaces[indentIndex] + "errors.rejectValue(");
			sbuff.append("\"" + nameOfControl + "\", \"text.checklength\");\n");
			--indentIndex;
			sbuff.append(spaces[indentIndex] + "}\n");

			messagesCode = "text.checklength";
			messagesContent = "This field must have minlength = " + minLength
					+ " and max length = " + maxLength;

			propOfMessage.setProperty(messagesCode, messagesContent);
		}

		return sbuff.toString();
	}

	public String generateCheckRange(String[] spaces, int indentIndex,
			String actionFormName, String nameOfControl, int typeOfControl,
			int minValue, int maxValue, Properties propOfMessage) {
		StringBuffer sbuff = new StringBuffer();
		String messagesCode = "";
		String messagesContent = "";

		switch (typeOfControl) {
		case TokenConstant.TEXTFIELD:
		case TokenConstant.TEXTAREA:
			/*
			 * try { int value = Integer.parseInt((String) user.getUsername());
			 * if (value < 1 || value > 100) { errors.rejectValue("username",
			 * "text.checkdate"); } } catch (Exception e) {
			 * errors.rejectValue("username", "text.checkdate"); }
			 */
			sbuff.append("\n");
			sbuff.append(spaces[indentIndex++] + "try{\n");
			sbuff.append(spaces[indentIndex]
					+ "int value = Integer.parseInt((String) "
					+ getValueFromActionForm(actionFormName, nameOfControl)
					+ ");\n");

			sbuff.append(spaces[indentIndex] + "if (value < " + minValue
					+ " || value > " + maxValue + ") {\n");
			++indentIndex;
			sbuff.append(spaces[indentIndex] + "errors.rejectValue(");
			sbuff.append("\"" + nameOfControl + "\", \"text.checkrange\");\n");
			--indentIndex;
			sbuff.append(spaces[indentIndex] + "}\n");
			--indentIndex;
			sbuff.append(spaces[indentIndex] + "}\n");

			sbuff.append(spaces[indentIndex++] + "catch (Exception e) {\n");
			sbuff.append(spaces[indentIndex] + "errors.rejectValue(");
			sbuff.append("\"" + nameOfControl + "\", \"text.checkrange\");\n");
			--indentIndex;
			sbuff.append(spaces[indentIndex] + "}\n");

			messagesCode = "text.checkrange";
			messagesContent = "This field must have value between " + minValue
					+ " and " + maxValue;

			break;
		}
		propOfMessage.setProperty(messagesCode, messagesContent);

		return sbuff.toString();
	}

	public String getValueFromActionForm(String actionFormName,
			String nameOfControl) {
		return ""
				+ ((char) (actionFormName.charAt(0) + 32))
				+ actionFormName.substring(1, actionFormName.length())
				+ ".get"
				+ ("" + ((char) (nameOfControl.charAt(0) - 32)) + nameOfControl
						.substring(1, nameOfControl.length())) + "()";
	}

	public void generateMessages(FileWriter messagesFileWriter,
			Properties propOfMessage) throws IOException {
		Set<Object> messageCodes = propOfMessage.keySet();

		for (Object messageCode : messageCodes) {
			messagesFileWriter.append(messageCode.toString() + "="
					+ propOfMessage.getProperty(messageCode.toString()) + '\n');
		}
	}
}